home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Interactive Reference Guide
/
C-C++ Interactive Reference Guide.iso
/
c_ref
/
csource5
/
338_01
/
as68.c
< prev
next >
Wrap
Text File
|
1989-12-01
|
9KB
|
286 lines
/* as68.c, the source of a 68000 assembler.... (root)
* (C) Copyright 1982 Steve Passe
* All Rights Reserved
*
* ver. 1.00
* created 10/7/82
*
* version 1.01
*
* 8/30/83 ver. 1.01 modified for Aztec ver. 1.05g smp
* 12/23/83 fixed 24 bit address bug in flush_rcrd smp
* 12/24/83 fixed lowercase a-f in S-records smp
*
* Oct-87 srd - fix 'char' - smp assumed chars were UNSIGNED - ha ha.
* Also, fix numerous bugs and break into overlays for small
* machines (like PDP-11, Whitesmith's compiler in particular)
* This version works on both IBM-PC (Microsoft C vers 4.0) and
* PDP-11 (TSX+, Whitesmith's RT-11 compiler). Seems solid.
* I am beginning to understand how it works...
* -Stuart R Dole, SAMKHYA Corp, 707-763-2800
*/
/* begincode */
/* includes */
#include <stdio.h>
#include "as68.h"
/* externals */
struct _symbol *symtbl = {0};
struct _symbol *syms_head = {0}; /* head of sym table free space */
char *syms_tail = NULL; /* tail of sym table free space */
int symspace = SYMTSIZE; /* bytes in symbol table */
int symbols = 0; /* number of symbols in table */
FLAG fatal = NO;
char pass = 1; /* present pass number, 1 or 2 */
unsigned line_count = 0; /* line number of source file */
unsigned list_count = 0; /* line # of list file */
long loc_counter = 0; /* address to assemble obj code */
int loc_plus = 0; /* increment to loc counter */
char lcksm = 0; /* bytes + addr. + count + lcksm == 0xff */
FLAG abs_long = YES; /* default to absolute long add.*/
FLAG rorg = NO; /* prog. counter relative flag */
FLAG do_label = YES; /* process label if set */
char statement[STMNT_SIZE] = {0}; /* statement line buffer */
char label[32] = {0}; /* bufr for label from preparse */
char instr[32] = {0}; /* bufr for mnem, psdo or macro */
char *opfld_ptr = NULL; /* pointer to operand field */
char stnt_typ = 0; /* statement type, instr, pseudo */
int wrap = 80; /* wrap column for list output */
FLAG trunc = NO; /* truncate lines in listing */
char source_name[FNAME_SIZE] = {0}; /* source file name */
int src_level = 0; /* source file level */
FILE *_src[SRCLEVELS] = {0}; /* source file descripters */
FLAG objchnl = 's'; /* Motorola S ('s') or nil ('x') */
FLAG obj_open = NO; /* object channel open flag */
char of_disk = NULL; /* default object file drive */
char object_name[FNAME_SIZE] = {0}; /* object file name */
FILE *obj_f = NULL; /* object file descripter */
FLAG lstchnl = NO; /* list channel(s) open */
FLAG nolist = NO; /* flag for list/nolist pseudos */
FLAG lcon = NO; /* list to console flag */
FLAG llst = NO; /* list to list device flag */
FLAG lfile = NO; /* list to file flag */
FLAG lfile_open = NO; /* list file open flag */
char lf_disk = NULL; /* default list file drive */
char list_name[FNAME_SIZE] = {0}; /* listing file name */
FILE *lst_f = NULL, *lst_d = NULL; /* listing file & dev descripter */
FLAG errchnl = YES; /* error channel(s) open */
FLAG econ = YES; /* errors to console flag */
FLAG elst = NO; /* errors to list device flag */
FLAG elfile = NO; /* errors to listing file */
FLAG efile = NO; /* errors to error file */
FLAG efile_open = NO; /* error file open flag */
char ef_disk = NULL; /* default error file drive */
char error_name[FNAME_SIZE] = {0}; /* error file name */
FILE *err_f = NULL; /* error file descripter */
struct _oprnd op1 = {0}, op2 = {0}; /* structs to hold operand val */
char code[12] = {0}; /* 12 minimum for overflow */
char buf[85] = {0};
long lex_val = 0L;
char *p = NULL;
extern struct _mtable mtable[];
/* things that were 'static' in overlays... */
FLAG any_errors = NO;
int err_stk[MAXERR] = {0}; /* these two used to be 'static', moved to */
int err_sp = MAXERR; /* root for overlay purposes */
char *stmnt_ptr = NULL; /* from ASETC.C, fcn obj_out */
long s_lc = 0L;
char s_buf[48] = "S"; /* init first character */
int s_cnt = 0; /* bytes in s_buf */
int s_x = 0; /* index into s_buf */
/* types */
char *nextfield();
struct _mtable *mnemsearch();
struct _ptable *psdosearch();
/* beginmain */
main(argc, argv)
int argc;
char *argv[];
{
register struct _ptable *pt; /* function ptr returned by psdosearch */
register struct _mtable *mt; /* function ptr returned by mnemsearch */
if (asinit(argc, argv)) { /*************** start pass loop... */
while (nextline()) {
/* parse line for label, instruction and operand field pointer */
if (preparse() == COMMENT) {
if (pass == 2) dump_code(MSG, code, 0); /* dump the line */
continue;
}
if (instr[0]) { /* mnemonic/pseudo-op/macro field is present) */
if (instr[31] && (pass == 2)) err_out(BAD_INSTR);
/* check for mnemonic */
if (mt = mnemsearch(instr)) {
stnt_typ = MNEMONIC;
pass == 1 ? p1_mnem(mt) : p2_mnem(mt);
}
/* or pseudo-op */
else if (pt = psdosearch(instr)) {
stnt_typ = PSEUDO; /* record the fact */
switch (pass) {
case 1:
(*pt->_p1)(pt->_psdo, pt->_arg);
if (pass == 2) continue;
break;
case 2:
(*pt->_p2)(pt->_psdo, pt->_arg);
if (pass == 3) goto finish;
}
}
/** or macro use */
else if (FALSE /** macros not used yet **/) {
/** MACROS NOT IMPLIMENTED in version 1.xx */
stnt_typ = MACRO;
}
else {
stnt_typ = NULL;
err_out(UNREC_INSTR);
dump_code (CODE, code, 0);
}
}
else {
if (pass == 2) {
dump_code (CODE, code, 0); /* label only line ? */
}
}
if (label[0] && do_label) {
label_do();
}
do_label = YES; /* reset for next line */
loc_counter += loc_plus; /* update loc_counter */
loc_plus = NULL; /* clear for next instruction */
if (fatal) { /* fatal system ERROR */
puts("\007\nFATAL SYSTEM ERROR!\007");
break;
}
} /* end of pass loop */
} /* endif(asinit()) */
/** close shop... */
finish:
finis();
}
/* endmain */
label_do()
{
register int x;
do_label = NO;
if (pass == 1) {
/** add as permanent (and/or relative) */
if (symenter(label, loc_counter, (rorg) ? 'r' : 'a')
== ERROR) {
fatal = YES;
puts("\007\nsymbol table FULL!\007");
return ERROR;
}
}
else { /* pass == 2 */
if (x = symsearch(label)) {
if (symtbl[x]._atr & 4) { /* redefined */
err_out(REDEF);
err_out(NULL); /* cause the dumping of this error */
if (symtbl[x]._val != loc_counter) {
err_out(PHASE);
err_out(NULL);
}
}
}
else {
err_out(UNDEF_SYMBOL); /* label never defined */
err_out(NULL); /* cause the dumping of this error */
}
}
return OK;
}
dump_code(typ, cdp, cdl)
int typ;
char *cdp;
int cdl;
{
register int x, y;
char buf[85];
char acode[20];
switch (typ) {
case CODE: /* dump all fields, including error stack */
case DATA: /* dump line, loc, code, pseudo, op/comments */
case MSG:
obj_out(typ, cdp, cdl);
if (!lstchnl) {
if (typ == CODE || typ == MSG) /* dump remaining op/com */
if (errchnl && any_errors) err_out(NULL); /* dump errors */
break;
}
if (!cdl) { /* print loc only if data */
sprintf(buf, " %4d ", line_count);
} else {
sprintf(buf, " %4d %06lx ", line_count, loc_counter);
}
x = 13;
if (cdl) {
hex_byt(acode, cdp, cdl); /* convert raw code to ascii hex */
for (y = 0; y < (cdl * 2); ) { /* for each byt in acode */
buf[x++] = acode[y++]; /* ...move to buf... */
if (!(y%4)) buf[x++] = ' '; /* ...if 4th byte add space */
}
}
while (x < 40) buf[x++] = ' '; /* pad rest with spaces */
buf[x] = '\0';
list_dump(buf); /* send it */
if (get_source(buf)) { /* dump the source */
list_dump(buf);
}
if (typ == DATA) break; /* let data sender flush */
goto flush; /* dump source */
case MDATA: /* dump loc, code, op/comments */
obj_out(typ, cdp, cdl);
if (!lstchnl) break;
hex_byt(acode, cdp, cdl); /* convert raw code to ascii hex */
for (x = 0; x < 13; ) buf[x++] = ' '; /* pad it */
for (y = 0; y < (cdl * 2); ) { /* for each byte in acode... */
buf[x++] = acode[y++]; /* ...move to buf... */
if (!(y%4)) buf[x++] = ' '; /* ...if 4th byte add space */
}
while (x < 40) buf[x++] = ' ';
buf[x] = '\0';
list_dump(buf);
if (get_source(buf)) { /* dump the source */
list_dump(buf);
}
else list_dump("\n"); /* terminate the data line */
break;
case FLUSH: /* dump remaining comment field, error stack */
flush:
while (get_source(buf)) {
/* if (buf[0] == '\n') break; */
list_dump("\t\t\t\t\t"); /* 5 tabs equals 40 spaces */
list_dump(buf);
}
if (errchnl && any_errors) err_out(NULL); /* dump errors */
break;
}
}